5.0 本章概述
Java和Scala定义简单method区别:
// java public String doSomething(int x) { // code here } // scala def doSomething(x: Int): String = { // code here }
Scala还可以使用下面方式,不指定返回值类型,不要求包裹body的大括号:
def plusOne(i: Int) = i + 1
- 除了上面例子的区别,Java和Scala还包括以下不同:
- 指定方法获取控制(显示)
- 给方法参数设置默认值的能力
- 调用方法时指定方法参数名字的能力
- 如何声明一个方法可能抛出的异常
- 方法里使用可变参数
5.1 控制方法范围
- 问题:Scala方法默认是公开的,想要如Java一样控制它的范围
5.1.1 解决方案
Scala从“更加限制”到“更加公开”有以下几个范围选项:
- 只有当前对象的当前实例可以获取这个方法,同一个类的其他实例不可以。
使用private[this]修饰符:
private[this] def isFoo = true
下面例子,方法doFoo使用了一个Foo对象的实例,但是isFoo方法声明成Object-private,因为当前Foo实例不能获取到其他实例的isFoo方法,所以下面代码不会编译:
class Foo { private[this] def isFoo = true def doFoo(other: Foo) { if (other.isFoo) { // this line won't compile // ... } } }
5.1.3 Private scope
存在于当前类和当前类的其他实例,和Java中使用private一样,把上面的private[this] 改为private就可以编译成功了:
class Foo { private def isFoo = true def doFoo(other: Foo) { if (other.isFoo) { // this now compiles // ... } } }
private方法,子类不可以获取:
class Animal { private def heartBeat {} } class Dog extends Animal { heartBeat // won't compile }
5.1.4 Protected scope
Protected方法子类可获取
class Animal { protected def breathe {} } class Dog extends Animal { breathe }
Java中protected方法可以被同一个包的其他类获取,Scala不是这样,下面不会编译:
package world { class Animal { protected def breathe {} } class Jungle { val a = new Animal a.breathe // error: this line won't compile } }
5.1.5 Package scope
当前包内所有成员可见,使用private[packageName]表示对当前包私有,下面doX可以被同一个包内所有类获取,doY只能被Foo类获取:
package com.acme.coolapp.model { class Foo { private[model] def doX {} private def doY {} } class Bar { val f = new Foo f.doX // compiles f.doY // won't compile } }
5.1.6 更多package等级控制
不同包等级权限不同
package com.acme.coolapp.model { class Foo { private[model] def doX {} private[coolapp] def doY {} private[acme] def doZ {} } } import com.acme.coolapp.model._ package com.acme.coolapp.view { class Bar { val f = new Foo f.doX // won't compile f.doY f.doZ } } package com.acme.common { class Bar { val f = new Foo f.doX // won't compile f.doY // won't compile f.doZ } }
5.1.7 Public scope
不添加任何权限修饰符,方法是公开的:
package com.acme.coolapp.model { class Foo { def doX {} } } package org.xyz.bar { class Bar { val f = new com.acme.coolapp.model.Foo f.doX } }
5.1.8 讨论
Table 5-1. Descriptions of Scala’s access control modifiers
Access modifier | Description | |
---|---|---|
private[this] | The method is available only to the current instance of the class | it’s declared in. |
private | The method is available to the current instance and other instances of the class it’s declared in. | |
protected | The method is available only to instances of the current class and subclasses of the current class. | |
private[model] | The method is available to all classes beneath the com.acme.coolapp.model package. | |
private[coolapp] | The method is available to all classes beneath the com.acme.coolapp package. | |
private[acme] | The method is available to all classes beneath the com.acme package. | |
(no modifier) | The method is public. |